/**
 * 
 */

/**
 * @author barretto
 *
 */
package br.unb.midialab.evo.osc;

import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

import br.unb.midialab.evo.ifs.OSCListener;
import netP5.NetAddress;
import oscP5.OscBundle;
import oscP5.OscMessage;
import oscP5.OscP5;

public class OSCMessager {

	/**
	 *
	 */
	private static final long serialVersionUID = 1L;
	OscP5 osc = null;
	private NetAddress myRemoteAddress = null;

	private List<OSCListener> listeners;

	public OSCMessager() {
		this.osc = new OscP5(this, 9999);
		listeners = new ArrayList<OSCListener>();
	}

	private OscP5 getOsc() {
		if (osc == null) {
			osc = new OscP5(this, 9999);
		}
		return osc;
	}

	void setMyRemoteAddress(NetAddress myRemoteAddress) {
		this.myRemoteAddress = myRemoteAddress;
	}

	NetAddress getMyRemoteAddress() {
		if (myRemoteAddress == null) {
			setMyRemoteAddress(new NetAddress("127.0.0.1", 9998));
		}
		return myRemoteAddress;
	}

	public synchronized void sendTranslationMessage(String fourChars) {
		OscBundle oscB = new OscBundle();
		OscMessage message = new OscMessage("/translation");
		// message.setAddrPattern("/test2");
		message.add(fourChars.toCharArray());
		oscB.add(message);
		// message.add(fourChars);
		// oscB.add(message);
		getOsc().send(oscB, getMyRemoteAddress());
	}

	public void sendStringMessage(String addrPattern, String content) {
		OscBundle oscB = new OscBundle();
		OscMessage message = new OscMessage(addrPattern);
		// message.setAddrPattern("/test2");
//		System.out.println(content);
		message.add(content);
		oscB.add(message);
		// message.add(fourChars);
		// oscB.add(message);
		getOsc().send(oscB, getMyRemoteAddress());
	}

	public synchronized void sendBangFlangerMessage(String mensagem,
			int changeFrequency) {

		final String twittie = mensagem;
		final int frequency = changeFrequency;

		Runnable bangThread = new Runnable() {

			public void run() {
				for (int i = 0; i < twittie.length(); i++) {
					Character c = twittie.charAt(i);
					// message.setAddrPattern("/test2");
					if (c.equals('1')) {
						sendBangMessage(c);
						try {
							// System.out.println((c) + " <- Sent to PD");
							Thread.sleep(frequency / twittie.length());
						} catch (InterruptedException ex) {
							Logger.getLogger(OSCMessager.class.getName()).log(
									Level.SEVERE, null, ex);
						}
					}
				}

			}
		};

		Thread bang = new Thread(bangThread);
		bang.start();
	}

	public synchronized void sendBangMessage(char c) {
		OscBundle oscB = new OscBundle();
		OscMessage message = new OscMessage("/bangflanger");
		Byte b = Byte.valueOf(String.valueOf(c));
		message.add(b);
		oscB.add(message);
		getOsc().send(oscB, getMyRemoteAddress());
	}

	/* incoming osc message are forwarded to the oscEvent method. */
	void oscEvent(OscMessage theOscMessage) {
		int index = -1;

		/* print the address pattern and the typetag of the received OscMessage */
		System.out.println("### received an osc message.");
		System.out.println(" addrpattern: " + theOscMessage.addrPattern());
		System.out.println(" typetag: " + theOscMessage.typetag());
		System.out.println(" arg0: " + theOscMessage.get(0).intValue());

		if (theOscMessage.checkAddrPattern("/removeBird") == true) {
			/* check if the typetag is the right one. */
			if (theOscMessage.checkTypetag("i")) {
				index = theOscMessage.get(0).intValue();
				System.out.println(index + "<-- index");
			}
		}

		if (index > -1) {
			for (OSCListener listener : listeners) {
				listener.removeBird(index-1);
			}
		}

	}

	public void register(OSCListener listener) {
		listeners.add(listener);
	}

	public void sendFloatArrayMessage(String addrPattern, Object[] content) {
		// TODO Auto-generated method stub
		OscBundle oscB = new OscBundle();
		OscMessage message = new OscMessage(addrPattern);
		// message.setAddrPattern("/test2");
//		System.out.println(content.toString());
		message.add(content);
		oscB.add(message);
		// message.add(fourChars);
		// oscB.add(message);
		getOsc().send(oscB, getMyRemoteAddress());
	}
}
